<?php

namespace app\admin\controller\user;

use app\common\controller\Backend;
use think\Db;

/**
 * 会员组管理
 *
 * @icon fa fa-users
 */
class Group extends Backend
{

    /**
     * @var \app\admin\model\UserGroup
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = model('UserGroup');
        $this->view->assign("statusList", $this->model->getStatusList());
    }

    public function add()
    {
        if ($this->request->isPost()) {
            $this->token();
        }
        $nodeList = \app\admin\model\UserRule::getTreeList();
        $this->assign("nodeList", $nodeList);
        return parent::add();
    }

    public function edit($ids = null)
    {
        if ($this->request->isPost()) {
            $this->token();
        }
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $rules = explode(',', $row['rules']);
        $nodeList = \app\admin\model\UserRule::getTreeList($rules);
        $this->assign("nodeList", $nodeList);
        return parent::edit($ids);
    }
    
    //同步根目录文件权限
    public function sync()
    {
        if ($this->request->isPost()) {
            $this->token();
        }
        $res = $this->wjsync();
        $this->success("同步成功");
        
    }

     /**
     * 同步目录和文件到数据库（防重复）
     */
    public function wjsync()
    {
        set_time_limit(300); // 防止大目录超时

        // 根目录路径（请根据实际修改）
        $root_dir = 'D:/phpstudy_pro/WWW/file_manage/public/doc1';

        if (!is_dir($root_dir)) {
            return json(['code' => 0, 'msg' => '根目录不存在：' . $root_dir]);
        }
        Db::name('directory')->delete(true); // 删除所有数据
        Db::name('file')->delete(true);       // 删除所有数据

        // 1. 递归扫描目录和文件
        $dirs  = [];
        $files = [];
        $this->scan($root_dir, $dirs, $files);

        if (empty($dirs) && empty($files)) {
            return json(['code' => 0, 'msg' => '未扫描到任何目录或文件']);
        }

        // 2. 去重：按 full_path 保留唯一目录
        $unique_dirs = [];
        foreach ($dirs as $dir) {
            $full_path = $this->normalizePath($dir['full_path']);
            if (!isset($unique_dirs[$full_path])) {
                $unique_dirs[$full_path] = [
                    'name'       => $dir['name'],
                    'full_path'  => $full_path,
                ];
            }
        }

        // 3. 查询已存在的目录
        $existing_dirs = [];
        if (!empty($unique_dirs)) {
            $paths = array_keys($unique_dirs);
            $existing_dirs = Db::name('directory')
                ->where('full_path', 'in', $paths)
                ->column('id', 'full_path'); // ['full_path' => id]
        }

        // 4. 构建目录 ID 映射表
        $dirIdMap = [];
        $newDirs  = [];

        foreach ($unique_dirs as $full_path => $dirInfo) {
            if (isset($existing_dirs[$full_path])) {
                $dirIdMap[$full_path] = $existing_dirs[$full_path];
            } else {
                $newDirs[] = [
                    'name'       => $dirInfo['name'],
                    'full_path'  => $full_path,
                    'created_at' => date('Y-m-d H:i:s')
                ];
            }
        }

        // 5. 插入新目录
        $inserted_dir_count = 0;
        if (!empty($newDirs)) {
            $chunks = array_chunk($newDirs, 100);
            foreach ($chunks as $chunk) {
                try {
                    Db::name('directory')->insertAll($chunk);
                } catch (\Exception $e) {
                    // 忽略重复键异常（极小概率）
                    trace('目录插入异常: ' . $e->getMessage(), 'error');
                }
            }
            $inserted_dir_count = count($newDirs);

            // 重新查询新插入的目录 ID
            $newPaths = array_column($newDirs, 'full_path');
            $newRecords = Db::name('directory')
                ->where('full_path', 'in', $newPaths)
                ->column('id', 'full_path');

            $dirIdMap = array_merge($dirIdMap, $newRecords);
        }

        // 6. 处理文件：统一路径 + 去重判断
        $existing_files = [];
        $file_paths = array_column($files, 'full_path');

        // 标准化所有文件路径
        $normalized_files = [];
        foreach ($files as $file) {
            $full_path = $this->normalizePath($file['full_path']);
            $parent_path = $this->normalizePath($file['parent_path']);

            $normalized_files[] = [
                'filename'    => $file['filename'],
                'full_path'   => $full_path,
                'parent_path' => $parent_path,
            ];
        }

        $file_paths = array_column($normalized_files, 'full_path');

        if (!empty($file_paths)) {
            $existing_files = Db::name('file')
                ->where('full_path', 'in', $file_paths)
                ->column('1', 'full_path'); // ['full_path' => 1]
        }

        // 7. 准备新文件数据
        $newFiles = [];
        foreach ($normalized_files as $file) {
            $full_path = $file['full_path'];

            // 跳过已存在的文件
            if (isset($existing_files[$full_path])) {
                continue;
            }

            $parent_dir_path = $file['parent_path'];

            if (!isset($dirIdMap[$parent_dir_path])) {
                // 父目录未找到（理论上不应发生）
                continue;
            }

            $newFiles[] = [
                'directory_id' => $dirIdMap[$parent_dir_path],
                'filename'     => $file['filename'],
                'full_path'    => $full_path,
                'created_at'   => date('Y-m-d H:i:s')
            ];
        }

        // 8. 插入新文件
        $inserted_file_count = 0;
        if (!empty($newFiles)) {
            $chunks = array_chunk($newFiles, 100);
            foreach ($chunks as $chunk) {
                try {
                    Db::name('file')->insertAll($chunk);
                } catch (\Exception $e) {
                    trace('文件插入异常: ' . $e->getMessage(), 'error');
                }
            }
            $inserted_file_count = count($newFiles);
        }

        // 9. 返回结果
        return json([
            'code' => 1,
            'msg'  => '同步完成',
            'data' => [
                'total_dirs'  => count($unique_dirs),
                'new_dirs'    => $inserted_dir_count,
                'total_files' => count($files),
                'new_files'   => $inserted_file_count,
            ]
        ]);
    }

    /**
     * 递归扫描目录
     */
    protected function scan($dir, &$dirs, &$files)
    {
        $items = array_diff(scandir($dir), ['.', '..']);

        foreach ($items as $item) {
            $path = $dir . DIRECTORY_SEPARATOR . $item;

            if (is_dir($path)) {
                $dirs[] = [
                    'name'       => basename($item),
                    'full_path'  => $path,
                ];
                $this->scan($path, $dirs, $files);
            } else {
                // ✅ 只处理 .html 文件
                if (pathinfo($item, PATHINFO_EXTENSION) !== 'html') {
                    continue; // 跳过非 html 文件
                }

                $files[] = [
                    'filename'    => $item,
                    'full_path'   => $path,
                    'parent_path' => dirname($path),
                ];
            }
        }
    }

    /**
     * 统一路径分隔符为 DIRECTORY_SEPARATOR（并去除多余分隔符）
     */
    protected function normalizePath($path)
    {
        // 统一为 DIRECTORY_SEPARATOR
        $path = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $path);

        // 去除重复分隔符（如 \\ 或 //）
        $path = preg_replace('/' . preg_quote(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, '/') . '+/', DIRECTORY_SEPARATOR, $path);

        return $path;
    }







}
